(ns forum.controller
  (:use  ring.util.response
         korma.core
         forum.models
         sandbar.stateful-session
         )
  (:require [forum.templates :as templates]))
  
(defn index
  "Index page handler"
  [req]
  (let [username (session-get :username)]
    (if (nil? username)
      (response (templates/login-page))
      (response (templates/home-page (select categories))))))




(defn topic
  "Handler for all topics from the same category"
  [req category-id]  
  (do
    (session-put! :categories_id category-id)
    (response (templates/topic-page (find-topics-by-category category-id)))
    ))

(defn post
  "Handler for all posts from the same topic"
  [req topic-id]
  (do
    (session-put! :topics_id topic-id)
    (response (templates/post-page (find-posts-by-topic topic-id) (session-get :username)))))

(defn login
  "Login Handler"
  [req]
  (let [params (:params req)]
    (if (empty? params)
      (response (templates/login-page))
      (if-not (nil? (find-user-by-username (get params "username")))
        (do
          (session-put! :username (get params "username"))
          (redirect "/"))
       (response (templates/login-page "Invalid username or password"))))))

(defn admin
  "Admin handler"
  [req]
  (let [username (session-get :username)
        params (:params req)]
    (if (nil? username)
      (redirect "/login")
      (do
        (if-not (empty? params)
          (let [id (inc (count (select posts)))
                user-id (:id (find-user-by-username username))]
            (insert posts (values (assoc params
                                    :id id
                                    :users_id user-id)))))
        (response (templates/admin-page))))))


(defn category
  "Create category handler"
  [req]
  (let [username (session-get :username)
        role (:role (find-user-by-username username))
        params (:params req)
        title (get params "title")
        description (get params "description")]
    (if-not (= role "admin")
      (redirect "/")
      (if (empty? params)
        (response (templates/category-page))
        (if (or (= title "")(= description ""))
          (redirect "/category")
          (do
            (insert categories (values {
                                    :id (generate-id categories)
                                    :title title
                                    :description description}))
            (redirect "/")))))))

(defn register
  "Registration handler"
  [req]
  (let [params (:params req)
        username (get params "username")
        password (get params "password")
        email (get params "email")]
      (if (empty? params)
        (response (templates/registration-page))
        (if (or (= username "") (= password "") (= email ""))
          (redirect "/register")
          (do
            (insert users (values {
                                    :id (generate-id users)
                                    :username username
                                    :password password
                                    :email email
                                    :role "member"}))
            (response (templates/login-page "You can now login")))))))

  
(defn thread
  "Create topic handler"
  [req]
  (let [username (session-get :username)
        users_id (:id (find-user-by-username (session-get :username)))
        params (:params req)
        title (get params "title")
        content (get params "content")
        categories_id (session-get :categories_id )
        topic-id (generate-id topics)]
      (if (empty? params)
        (response (templates/thread-page))
        (if (or (= title "") (= content ""))
          (redirect "/thread")
          (do
            (insert topics (values {
                                    :id topic-id
                                    :title title
                                    :users_id users_id
                                    :categories_id (Integer/parseInt categories_id)}))
            (insert posts (values {
                                    :id (generate-id posts)
                                    :content content
                                    :users_id users_id
                                    :topics_id topic-id}))
            (response (templates/topic-page (find-topics-by-category categories_id))))))))


(defn addpost
  "Add post to topic handler"
  [req]
  (let [users_id (:id (find-user-by-username (session-get :username)))
        params (:params req)
        content (get params "content")
        topics_id (session-get :topics_id )]
      (if (empty? params)
        (response (templates/addpost-page))
        (if (= content "")
          (redirect "/addpost")
          (do
            (insert posts (values {
                                    :id (generate-id posts)
                                    :quote (session-get :quote)
                                    :content content
                                    :users_id users_id
                                    :topics_id (Integer/parseInt topics_id)
                                    }))
            (session-delete-key! :quote)
            (response (templates/post-page (find-posts-by-topic topics_id) (session-get :username))))))))

(defn viewusers
  "View all users"
  [req]
  (let [username (session-get :username)
        role (:role (find-user-by-username username))]
    (if-not (= role "admin")
      (redirect "/")
      (response (templates/viewusers-page (select users))))))

(defn profile
  "View single user profile"
  [req user-id]
  (let [user (find-user-by-id (Integer/parseInt user-id))]
    (response (templates/profile-page user))))

(defn deletepost
  "Delete post"
  [req post-id]
  (let [username (session-get :username)
        role (:role (find-user-by-username username))
        topics_id (session-get :topics_id )]
    (if-not (= role "admin")
      (redirect "/")
      (do
        (delete-post-by-id (Integer/parseInt post-id))
        (response (templates/post-page (find-posts-by-topic topics_id) (session-get :username)))))))
 
(defn editu
  "Edit user"
  [req user-id]
  (let [user (find-user-by-id (Integer/parseInt user-id))
        params (:params req)]
    (session-put! :user-id (:id user))
      (if (empty? params)
        (response (templates/edituser-page user)))))

(defn edituser
  [req]
  (let [user-id (session-get :user-id)
        params (:params req)
        username (get params "username")
        password (get params "password")
        email (get params "email")
        role (get params "role")]
    (do
        (update users
                    (set-fields {:username username
                                 :password password
                                 :email email
                                 :role role})
                    (where {:id user-id}))
        (response (templates/viewusers-page (select users))))))

(defn editp
  "Edit post"
  [req post-id]
  (let [post (find-post-by-id post-id)
        params (:params req)]
    (session-put! :post-id (:id post))
      (if (empty? params)
        (do
        (println (:content post))
        (response (templates/editpost-page post))))))

(defn editpost
  [req]
  (let [post-id (session-get :post-id)
        params (:params req)
        content (get params "content")]
    (do
        (update posts
                    (set-fields {:content content})
                    (where {:id post-id}))
        (redirect "/"))))

(defn editt
  "Edit post"
  [req topic-id]
  (let [topic (find-topic-by-id topic-id)
        params (:params req)]
    (session-put! :topic-id (:id topic))
      (if (empty? params)
        (response (templates/edittopic-page topic)))))

(defn edittopic
  [req]
  (let [topic-id (session-get :topic-id)
        params (:params req)
        title (get params "title")]
    (do
        (update topics
                    (set-fields {:title title})
                    (where {:id topic-id}))
        (redirect "/"))))

(defn deletetopic
  "Delete post"
  [req topic-id]
  (let [username (session-get :username)
        role (:role (find-user-by-username username))
        ]
    (if-not (= role "admin")
      (redirect "/")
      (do
        (delete-topic-by-id (Integer/parseInt topic-id))
        (redirect "/")))))

(defn viewnews
  "View news"
  [req]
  (let [username (session-get :username)]
    (if (nil? username)
      (response (templates/login-page))
      (response (templates/viewnews-page (select news))))))

(defn addnews
  "Delete post"
  [req]
  (let [username (session-get :username)
        role (:role (find-user-by-username username))]
    (if-not (= role "admin")
      (redirect "/")
      (response (templates/addnews-page)))))

(defn submitnews
  "Delete post"
  [req]
  (let [username (session-get :username)
        params (:params req)
        content (get params "content")
        title (get params "title")
        user-id (:id (find-user-by-username username))]
    (do 
        (insert news (values {
                                    :id (generate-id news)
                                    :title title
                                    :content content
                                    :users_id user-id}))
        (response (templates/viewnews-page (select news))))))

(defn quoterender
  [req post-id]
  (let [username (session-get :username)
        post (find-post-by-id post-id)
        params (:params req)]
      (if (nil? username)
         (redirect "/")
         (if (empty? params)
        (do
          (session-put! :quote (:content post))
          (response (templates/reply-page post)))))))


(defn inbox
  "View news"
  [req]
  (let [username (session-get :username)
        user-id (:id (find-user-by-username username))]
    (if (nil? username)
      (response (templates/login-page))
      (response (templates/inbox-page (select messages (where {:users_id user-id})))))))

(defn outbox
  "View news"
  [req]
  (let [username (session-get :username)
        user-id (:id (find-user-by-username username))]
    (if (nil? username)
      (response (templates/login-page))
      (response (templates/outbox-page (select messages (where {:sender_id user-id})))))))

(defn message
  "View news"
  [req message-id]
  (let [username (session-get :username)]
    (if (nil? username)
      (response (templates/login-page))
      (response (templates/message-page (first (select messages (where {:id (Integer/parseInt message-id)}))))))))

(defn sendmessage
  "send message"
  [req user-id]
  (let [username (session-get :username)]
    (if (nil? username)
      (response (templates/login-page))
      (do
        (session-put! :receiver (Integer/parseInt user-id))
        (response (templates/sendmessage-page))))))

(defn messagereply
  "send message"
  [req message-id]
  (let [message (find-message-by-id (Integer/parseInt message-id))
        username (session-get :username)]
    (if (nil? username)
      (response (templates/login-page))
      (do
        (session-put! :receiver (:users_id message))
        (session-put! :quote (:content message))
        (response (templates/sendmessage-page))))))

(defn sendm
  "Send"
  [req]
  (let [username (session-get :username)
        params (:params req)
        quote (session-get :quote)
        content (get params "content")
        title (get params "title")
        sender(:id (find-user-by-username username))
        receiver (session-get :receiver)]
    (do 
        (insert messages (values {
                                    :id (generate-id messages)
                                    :title title
                                    :quote quote
                                    :content content
                                    :sender_id sender
                                    :users_id receiver}))
        (redirect "/"))))

(defn search
  "Search"
  [req]
  (let [username (session-get :username)]
    (if (nil? username)
      (response (templates/login-page))
      (response (templates/search-page)))))

(defn searchp
  [req]
  (let [params (:params req)
        key (get params "key")]
    (response (templates/searchresult-page (search-posts key)))
    ))
  
(defn logout
  "Logout handler"
  [req]
  (do
    (session-delete-key! :username)
    (redirect "/")))